/*
 * Created on Feb 17, 2004
 *
 * Author: Sandeep Prakash
 * Project: Sucxentv2 (using leaf nodes only)
 */
package dbsucxentW.storageEdgeW.parserW;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import dbsucxentW.storageEdgeW.entitiesW.LeafNode;
import dbsucxentW.storageEdgeW.entitiesW.LeafNodeCollection;
import dbsucxentW.storageEdgeW.loadersW.Store;
import dbsucxentW.constantW.EdgeConstant;


/**
 * @author Administrator
 *
 *
 */
public class BranchOrderDecorator extends NodeExtractor
{
	/*klarinda 20060823 - are these used?
	protected final static int START_ELEMENT = 0;
	protected final static int END_ELEMENT = 1;

	protected int _state = -1;
	protected int _branchOrder = 0;
	*/

	private int _checker = 0;

	/*klarinda 20060905 bulk loader
	private int _ordinal;
	private int counter = 0;
	private int running = 0;
	*/

	//
	//This class stores the result of the first pass.
	//
	//klarinda 20060901 - not used in Edge protected DocumentSummary _summary;
	protected Store _store;
	//
	//Last branch_order..to check for continuity
	//
	protected int _prevBranchOrder = -1;
	protected int _branchOrderCount = 1;

	// nodes kept here
	private LeafNodeCollection _nodes;
	private int _oldDepth;
	private String[] _oldNames;

	/**
	 * @return
	 */
	/*klarinda 20060901 - not used in Edge
	public DocumentSummary getSummary() {
		return _summary;
	}
	*/
	/**
	 *
	 */
	public BranchOrderDecorator()  {
		super();
		//klarinda 20060901 - not used in Edge _summary = new DocumentSummary();
	}

	public BranchOrderDecorator( LeafNodeCollection nodes, Store store) {
		super();
//		System.out.println( "BranchOrderDecorator");//klarinda 20060822
		_nodes = nodes;
		//klarinda 20060901 - not used in Edge _summary = new DocumentSummary();
		_oldDepth = 0;
		_store = store;
		createFiles();//klarinda 20060905 bulk loader
	}


	/* Set start state again.
	 */
	protected void attributes(Attributes attributes) {
//		System.out.println( "BranchOrderDecorator.attributes()");//klarinda 20060822
		int attrCount = attributes.getLength();

		//klarinda 20060823 - is this used? int tmpBranchOrder = _branchOrder;

		for( int i = 0; i < attrCount; i++ ){
			_path.append( ".@" );
			_path.append( attributes.getQName( i ) );
			_path.append( "#" );
			_leafValue = new StringBuilder( attributes.getValue( i ) );
			//klarinda 20060828 _order++;
			_depth++;

			//extend BS
			_ancestorId[_depth] = _order;
			//_elementName[_depth] = attributes.getQName( i );

//			System.out.println( "BranchOrderDecorator.attributes(), path       : " + _path);			//klarinda 20060822
//			System.out.println( "BranchOrderDecorator.attributes(), depth      : " + _depth);			//klarinda 20060822
//			System.out.println( "BranchOrderDecorator.attributes(), order      : " + _order);			//klarinda 20060822
//			System.out.println( "BranchOrderDecorator.attributes(), leafValue  : " + _leafValue);		//klarinda 20060822

			//klarinda 20060828 leaf();
			leafAttribute();	//klarinda 20060828

			//klarinda 20060823 - is this used? _branchOrder = _depth;

			_depth--;
			clearPath();

		}

		/*klarinda 20060823 - is this used?
		_branchOrder = tmpBranchOrder;

		if( attributes.getLength() > 0 ){
			_branchOrder = _depth;
		}
		*/
	}

	/*
	 * Set end state.
	 */
	public void endElement(String uri, String localName, String qName) throws SAXException {
		super.endElement(uri, localName, qName);

		//klarinda 20060623 - moved to super;_state = END_ELEMENT;
	}

	/*
	 * Set start state.
	 */
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//		System.out.println( "BranchOrderDecorator.startElement()");			//klarinda 20060822

		/*klarinda 20060823 - is this used?
		if( _state != START_ELEMENT ){
			_state = START_ELEMENT;
			//Assign branch_order
			_branchOrder = _depth;
		}
		*/

		super.startElement(uri, localName, qName, attributes);

	}


	protected void leaf(){
//		System.out.println( "BranchOrderDecorator.leaf()");			//klarinda 20060822

		_checker++;

		_oldDepth = _depth;
		_oldNames = _elementName;


		LeafNode node = new LeafNode();

		node.setDocId(_store.getDocId());	//k20070525
		node.setOrder( _ancestorId[_depth] );
		node.setDescendantId( _order );
		node.setPath( _nodes.getPathId( _path.toString() , _store) );
		node.setValue( _leafValue.toString().trim() );
		node.setParentId(_ancestorId[_depth - 1]);
		node.setIsLeaf(true);
		node.setDepth(_depth);

		if(_leafValue.toString().trim().length() >= EdgeConstant.LARGETEXTDATA) //k20070525 add textcontent & attrcontent
			node.setIsLargeTextData(true);

//		System.out.println( "BranchOrderDecorator.leaf(), depth      : " + _depth);							//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.leaf(), ancID      : " + _ancestorId[_depth]);			//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.leaf(), parentID   : " + _ancestorId[_depth-1]);			//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.leaf(), order(descId): " + _order);						//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.leaf(), leafValue  : " + _leafValue.toString().trim());	//klarinda 20060822

		//klarinda 20060905 bulk loader
		try{
			_writers[EdgeConstant.EDGE_TABLE].append(node.bulkLoad());
			_writers[EdgeConstant.EDGE_TABLE].newLine();
			if(node.getIsLargeTextData()) { //k20070525 add textcontent & attrcontent
				_writers[EdgeConstant.TEXTCONTENT_TABLE].append(node.bulkLoadTextContent());
				_writers[EdgeConstant.TEXTCONTENT_TABLE].newLine();
			}
		} catch (IOException e) {
			System.out.println("ERR at bulk load leaf node");
			System.out.println(e.getMessage());
		}
		//end of klarinda
		/* klarinda 20060905 bulk loader
		_nodes.add( node );

		//descendant manager
		//_descendant.insert(node,_depth);
		//Launcher.getLoggerInstance().info("Inserted node id " + node.getOrder() + ": end  d " + _order + " at depth" + _depth + " of " + _path.toString());

		counter++;
		running++;

		//new area
		if (counter > 10000){  		//klarinda 20060901 initially > 5001
			Launcher.getLoggerInstance().info(running + "nodes");
			try{
				//Launcher.getLoggerInstance().info("storan");
				_store.store( _nodes );
				_nodes.clear();

			} catch (Exception e) {
				Launcher.getLoggerInstance().info("erroar");
				System.exit(0);
			}
			counter = 0;
		}
		//Launcher.getLoggerInstance().info( "LeafNode " + _path.toString() + " depth " + _depth);
		*/
	}

	protected void nonLeaf() {
//		System.out.println( "BranchOrderDecorator.nonLeaf()");			//klarinda 20060822

		_checker++;

		_oldDepth = _depth;
		_oldNames = _elementName;

		//klarinda 20060823 what's this used for? _summary.setCValue( _branchOrder, _order );

		LeafNode node = new LeafNode();

		node.setDocId(_store.getDocId());	//k20070525
		node.setOrder( _ancestorId[_depth] );
		node.setDescendantId( _order );
		node.setPath( _nodes.getPathId( _path.toString() , _store) );
		node.setParentId(_ancestorId[_depth - 1]);
		node.setIsLeaf(false);
		node.setDepth(_depth);

//		System.out.println( "BranchOrderDecorator.nonLeaf(), depth      : " + _depth);						//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.nonLeaf(), ancID      : " + _ancestorId[_depth]);			//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.nonLeaf(), parentID   : " + _ancestorId[_depth-1]);		//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.nonLeaf(), order(descId): " + _order);					//klarinda 20060822

		//klarinda 20060905 bulk loader
		try{
			_writers[EdgeConstant.EDGE_TABLE].append(node.bulkLoadNonLeaf());
			_writers[EdgeConstant.EDGE_TABLE].newLine();
		} catch (IOException e) {
			System.out.println("ERR at bulk load leaf node");
			System.out.println(e.getMessage());
		}
		//end of klarinda

		/* klarinda 20060905 bulk loader
		_nodes.add( node );

		//descendant manager
		//_descendant.insert(node,_depth);
		//Launcher.getLoggerInstance().info("Inserted node id " + node.getOrder() + ": end  d " + _order + " at depth" + _depth + " of " + _path.toString());

		counter++;
		running++;

		//new area
		if (counter > 10000){
			Launcher.getLoggerInstance().info(running + " nodes");

			try{
				_store.store( _nodes );
				_nodes.clear();

			} catch (Exception e) {
				Launcher.getLoggerInstance().info("erroar");
				System.exit(0);
			}
			counter = 0;
		}
		//Launcher.getLoggerInstance().info( "Node " + _path.toString() + " depth " + _depth);
		*/
	}

	//klarinda 20060828
	protected void leafAttribute(){
//		System.out.println( "BranchOrderDecorator.leafAttribute()");			//klarinda 20060822

		_checker++;

		_oldDepth = _depth;
		_oldNames = _elementName;


		LeafNode node = new LeafNode();

		//node.setOrder( _ancestorId[_depth] );
		//node.setDescendantId( _order );
		node.setDocId(_store.getDocId());	//k20070525
		node.setPath( _nodes.getPathId( _path.toString() , _store) );
		node.setValue( _leafValue.toString().trim() );
		node.setParentId(_ancestorId[_depth - 1]);
		node.setIsLeaf(true);
		node.setIsAttribute(true);
		node.setDepth(_depth);

		if(_leafValue.toString().trim().length() >= EdgeConstant.LARGETEXTDATA) //k20070525 add textcontent & attrcontent
			node.setIsLargeTextData(true);

//		System.out.println( "BranchOrderDecorator.leafAttribute(), depth      : " + _depth);							//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.leafAttribute(), parentID   : " + _ancestorId[_depth-1]);			//klarinda 20060822
//		System.out.println( "BranchOrderDecorator.leafAttribute(), leafValue  : " + _leafValue.toString().trim());	//klarinda 20060822

		//klarinda 20060905 bulk loader
		try{
			_writers[EdgeConstant.ATTRIBUTE_TABLE].append(node.bulkLoadAttribute());
			_writers[EdgeConstant.ATTRIBUTE_TABLE].newLine();
			if(node.getIsLargeTextData()) { //k20070525 add textcontent & attrcontent
				_writers[EdgeConstant.ATTRCONTENT_TABLE].append(node.bulkLoadAttrContent());
				_writers[EdgeConstant.ATTRCONTENT_TABLE].newLine();
			}
		} catch (IOException e) {
			System.out.println("ERR at bulk load leaf node");
			System.out.println(e.getMessage());
		}
		//end of klarinda
		/*klarinda 20060905 bulk loader
		_nodes.add( node );

		if (counter > 10000){
			Launcher.getLoggerInstance().info(running + " nodes");

			try{
				_store.store( _nodes );
				_nodes.clear();

			} catch (Exception e) {
				Launcher.getLoggerInstance().info("erroar");
				System.exit(0);
			}
			counter = 0;
		}
		*/
	}

	public void endDocument() throws SAXException {
		//Launcher.getLoggerInstance().info( "DocEnd");
		_nodes.completeProcessing();

		//klarinda 20060905 bulk loader
		System.out.println("BranchOrderDecorator.endDocument() closing all writers");
		try{
			_writers[EdgeConstant.ATTRIBUTE_TABLE].flush();
			_writers[EdgeConstant.ATTRIBUTE_TABLE].close();
			_writers[EdgeConstant.EDGE_TABLE].flush();
			_writers[EdgeConstant.EDGE_TABLE].close();
			//klarinda 20070525 add textcontent & attrcontent
			_writers[EdgeConstant.TEXTCONTENT_TABLE].flush();
			_writers[EdgeConstant.TEXTCONTENT_TABLE].close();
			_writers[EdgeConstant.ATTRCONTENT_TABLE].flush();
			_writers[EdgeConstant.ATTRCONTENT_TABLE].close();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
		//end of klarinda
		super.endDocument();

		//Launcher.getLoggerInstance().info( "No. of leaf nodes (for confirmation) = " + _checker );
	}

	//klarinda 20060904 bulk loading
	private void createFiles(){
		String fname;
		_writers = new BufferedWriter[EdgeConstant.NO_OF_TABLES];
		System.out.println("BranchOrderDecorator.createFiles()");
		//only create ATTRIBUTE & EDGE files
		try{

			// add by erwin 2007-07-04
			File dir1 = new File(".");
			EdgeConstant.BULKFILEPATH = dir1.getCanonicalPath() +"\\bulk\\";
			// end

			fname = EdgeConstant.BULKFILEPATH + EdgeConstant.TABLE_NAMES[EdgeConstant.EDGE_TABLE] + ".tbl";
			System.out.println("BranchOrderDecorator.createFiles(): "+fname);
			_writers[EdgeConstant.EDGE_TABLE] = new BufferedWriter(new FileWriter(fname));

			fname = EdgeConstant.BULKFILEPATH + EdgeConstant.TABLE_NAMES[EdgeConstant.ATTRIBUTE_TABLE] + ".tbl";
			System.out.println("BranchOrderDecorator.createFiles(): "+fname);
			_writers[EdgeConstant.ATTRIBUTE_TABLE] = new BufferedWriter(new FileWriter(fname));

			//klarinda 20070525 add TEXTCONTENT & ATTRCONTENT
			fname = EdgeConstant.BULKFILEPATH + EdgeConstant.TABLE_NAMES[EdgeConstant.TEXTCONTENT_TABLE] + ".tbl";
			System.out.println("BranchOrderDecorator.createFiles(): "+fname);
			_writers[EdgeConstant.TEXTCONTENT_TABLE] = new BufferedWriter(new FileWriter(fname));

			fname = EdgeConstant.BULKFILEPATH + EdgeConstant.TABLE_NAMES[EdgeConstant.ATTRCONTENT_TABLE] + ".tbl";
			System.out.println("BranchOrderDecorator.createFiles(): "+fname);
			_writers[EdgeConstant.ATTRCONTENT_TABLE] = new BufferedWriter(new FileWriter(fname));
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}

		System.out.println("BranchOrderDecorator.createFiles() success");
	}

}
